#ifndef FSM_HPP
#define FSM_HPP

#include <iostream>

class DoorFSM {
 public:
  enum State { LOCKED, UNLOCKED, CLOSED, OPENED, HALF_OPEN, JAMMED };

  DoorFSM() : state(LOCKED) {
  }

  void lock() {
    if (state != LOCKED) {
      state = LOCKED;
      std::cout << "Door is now locked." << std::endl;
    }
  }

  void unlock() {
    if (state == LOCKED) {
      state = UNLOCKED;
      std::cout << "Door is now unlocked." << std::endl;
    }
  }

  void open() {
    if (state == CLOSED || state == UNLOCKED || state == HALF_OPEN) {
      state = OPENED;
      std::cout << "Door is now opened." << std::endl;
    }
  }

  void close() {
    if (state == OPENED || state == HALF_OPEN) {
      state = CLOSED;
      std::cout << "Door is now closed." << std::endl;
    }
  }

  void halfOpen() {
    if (state == CLOSED || state == OPENED) {
      state = HALF_OPEN;
      std::cout << "Door is now half open." << std::endl;
    }
  }

  void jam() {
    if (state != JAMMED) {
      state = JAMMED;
      std::cout << "Door is now jammed." << std::endl;
    }
  }

  void unjam() {
    if (state == JAMMED) {
      state = CLOSED;
      std::cout << "Door is now unjammed and closed." << std::endl;
    }
  }

  State getState() const {
    return state;
  }

 private:
  State state;
};

#endif  // FSM_HPP
